/*
 * 文 件 名:  VelocityTemplateManager.java
 * 版    权:   深圳埃思欧纳信息咨询有限公司版权所有. YYYY-YYYY,  All rights reserved
 * 描    述:   <描述>
 * 修 改 人:  honny.huang
 * 修改时间: 2011-2-17
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.velocity;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

import com.ue.data.DataRow;
import com.ue.data.DataTable;
import com.ue.data.mapping.Column;
import com.ue.log.LogManager;
import com.ue.util.StringHelper;

/**
 * <一句话功能简述> <功能详细描述>
 *
 * @author honny.huang
 * @version [版本号, 2011-2-17]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */

public class VelocityTemplateManager2 
{
	//获取模板引擎 
	static VelocityEngine ve = new VelocityEngine();
	
	/**
	 * 初始化velocity模板
	 * <功能详细描述>
	 * 
	 * @return void [返回类型说明]
	 * @exception throws [违例类型] [违例说明]
	 * @see [类、类#方法、类#成员]
	 */
	private static void init()
	{
		//模板文件所在的路径
		String path = VelocityMailConstants2.MAIL_PATH;	
      	//设置参数
		ve.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, path);
        //处理中文问题
		ve.setProperty(Velocity.INPUT_ENCODING,"UTF-8");
		ve.setProperty(Velocity.OUTPUT_ENCODING,"UTF-8");
		//初始化模板，否则页面中文乱码
		ve.init();
	}
	
	/**
	 * 获取带后缀的模板文件名称
	 * <功能详细描述>
	 * @param strTemplateName
	 * @return
	 * 
	 * @return String [返回类型说明]
	 * @exception throws [违例类型] [违例说明]
	 * @see [类、类#方法、类#成员]
	 */
	private static String getTemplateName(String strTemplateName)
	{
		String strTemplate = "";
		if(StringHelper.isNotNullAndEmpty(strTemplateName))
		{
			strTemplate = strTemplateName + ".vm";
		}
		return strTemplate;
	}
	
	/**
	 * 邮件模板处理,返回邮件文本内容
	 * <功能详细描述>
	 * @param fileName
	 * @param param
	 * @return
	 * 
	 * @return String [返回类型说明]
	 * @exception throws [违例类型] [违例说明]
	 * @see [类、类#方法、类#成员]
	 */
	 public static String builder(String strTemplateName, Map<String, Object> param)
	 {
		 LogManager.debug("Enter VelocityTemplateManager.builder()");
		 init();
		 Template template = null;
		 try 
		 {
			//取得velocity的模版 
			String templateName = getTemplateName(strTemplateName);
			template = ve.getTemplate(templateName); 
		 }catch (Exception e) 
		 {
	    	LogManager.error("获取邮件模板失败：" + e.getMessage());
	    	return "";
		 }
		 //获取上下文
		 VelocityContext context = new VelocityContext();
         Iterator<String> it = param.keySet().iterator();
         //循环参数
         while (it.hasNext()) 
         {
		     String key=it.next().toString();
		     Object objectValue = param.get(key);
		     //判断Object对象所属的类型，根据不同的类型做处理
		     if (objectValue instanceof List<?>)
		     {
		    	 //当objectValue为List类型时，直接以key、value的方式存储到上下文，模板中采用#foreach循环输出
		    	 context.put(key,objectValue); 
		     }
		     else if(objectValue instanceof DataTable)
		     {
		    	 List<Map<String, Object>> dtEmailList = new ArrayList<Map<String, Object>>();
		    	 //得到DataTable类型的value的值
		    	 DataTable dTable =  (DataTable) objectValue;
		    	 if(null !=dTable && dTable.getRows().size() > 0)
		    	 {
		    		 for(int i = 0; i < dTable.getRows().size(); i++)
			    	 {
		    			 Map<String , Object> listParam = new  HashMap<String , Object>();
			    		//得到一条记录
				         DataRow localDataRow = (DataRow)dTable.getRows().get(i);
				         //循环dataTable列名
				         for (Column localColumn : dTable.getColumns().values()) 
				         {   
				        	 /* 给使用者提供多种选择：
				        	  * 1、当确定dt中只有一条记录时，按定义的规则改变字段名，防止与方法中的传值参数冲突，然后以key、value的方式存储到上下文，最后模板中直接输出；
				        	  * 2、不管dt中有多少条数据，都存储在List<Map<String, Object>>中，模板中采用#foreach循环输出
				        	  */
				        	 if(i == 0) 
				        	 {
				        		 //按定义的规则改变字段名，以key、value的方式存储到上下文中
				        		 context.put(key+"_first_"+localColumn.getName(), localDataRow.get(localColumn));
				        	 }
				        	 //将列名和对应的值以key、value的方式存储在 Map<String , Object> listParam中
				        	 listParam.put(localColumn.getName(), localDataRow.get(localColumn));
				         }
				         //将hashMap<k,v>添加到list中
				         dtEmailList.add(listParam);
			    	 }
		    		 //将DataTable转化成list后以key、value的方式存储到上下文中
		    		 context.put(key,dtEmailList); 
		    	 }
		     }
		     else 
		     {
		    	 String value=String.valueOf(objectValue);
			     //把数据填入上下文，通俗点说就是设置数据，供页面模版替换成显示的数据
			     context.put(key,value); 
			 }
		 }
         //输出流
	     StringWriter writer = new StringWriter(); 
		 //转换输出 
	     template.merge(context, writer); 
	     //得到模板内容
		 String templateContent = writer.toString();
		 writer.flush();    
	     try 
	     {
			writer.close();
		 }catch (IOException e) 
		 {
			e.printStackTrace();
		 }   
		 LogManager.debug("Exit VelocityTemplateManager.builder()");
         return templateContent;
	 }
	 
		 
		 //调试
		 public static String test() 
		 {
			 
			 List<HashMap<String, String>> dtEmailList = new ArrayList();
			 for(int i = 0; i<2 ; i++)
			 {
				 HashMap<String , String> param = new  HashMap<String , String>();
				 if (i == 0) 
				 {
					 param.put("id", "1");
				     param.put("userName", "你");
				 }
				 else 
				 {
					 param.put("id", "2");
				     param.put("userName", "我");
				 }   
				     dtEmailList.add(param);
			 }	 
			 
			 System.out.println(dtEmailList.size());  //2
			 //取得velocity的模版 
			 Template template = ve.getTemplate("test.vm"); 
			 System.out.println("=======================");
			 //获取上下文
			 VelocityContext context = new VelocityContext();
			 //list里装的是map<k,v>，把list数据填入上下文，在模板中采用foreach循环得到map<k,v>数据
	         context.put("tempList",dtEmailList); 
		     StringWriter writer = new StringWriter(); 
			 //转换输出 
		     template.merge(context, writer); 
			 String templateContent = writer.toString();
			 writer.flush();    
			 System.out.println("==================="); 
			 System.out.println(templateContent); 
			 System.out.println("====================="); 
		     try 
		     {
				writer.close();
			 }catch (IOException e) 
			 {
				e.printStackTrace();
			 }    
	        return templateContent;
			
		 }
		 
		 //调试
		 public static void main(String[] args) 
		 {
			 //初始化模板
			 VelocityTemplateManager2.init();
			 VelocityTemplateManager2.test();
			 
//			 HashMap<String , String> param = new  HashMap<String , String>();
////				 param.put("id", "1");
////			     param.put("userName", "你");
//			     Iterator<String> it = param.keySet().iterator();
//		         //循环参数
//		         while (it.hasNext()) 
//		         {
//				     String key=it.next().toString();
//				     String value=String.valueOf(param.get(key));
//				     //把数据填入上下文，通俗点说就是设置数据，供页面模版替换成显示的数据
//				     HashMap<String , String> paranp = new  HashMap<String , String>();
//				     paranp.put(key, value);
//				 }
//				 
//				 //输出流
//			     StringWriter writer = new StringWriter(); 
//				 //转换输出 
			  
			 
		 }

}
